package cn.moon.server.handler;

import cn.moon.protocol.ProxyMessage;
import cn.moon.server.channel.ServerChannelManager;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.function.BiFunction;


/**
 * 入口处理器
 * 处理外部消息
 */
@Slf4j
public class ServerHandler extends SimpleChannelInboundHandler<ProxyMessage> {


    private final HashMap<Byte, BiFunction<Channel, ProxyMessage, Void>> funcMap = new HashMap<>();

    public ServerHandler(){

        BiFunction<Channel, ProxyMessage, Void> connect = ((channel, message) -> {

            log.debug("======== 客户端连接 ========");
            // TODO: 验证权限
            ServerChannelManager.setBridgeChannel(channel);
            return null;
        });

        BiFunction<Channel, ProxyMessage, Void> disconnect = ((channel, message) -> {

            log.debug("======== 客户端断开连接 ========");

            ServerChannelManager.removeBridgeChannel(channel);
            return null;
        });

        BiFunction<Channel, ProxyMessage, Void> forward = ((channel, message) -> {

            log.debug("======== 请求回传 ========");

            ServerChannelManager.portalChannelForward(message.getChannelId(), message.getData());

            return null;
        });

        funcMap.put(ProxyMessage.CONNECT, connect);
        funcMap.put(ProxyMessage.FORWARD, forward);
        funcMap.put(ProxyMessage.DISCONNECT, disconnect);
    }


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
        log.debug("======== BridgeHandler channelRead0 ========");

        funcMap.get(proxyMessage.getType()).apply(ctx.channel(), proxyMessage);

    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        Channel channel = ctx.channel();
        if (channel.isActive()) {
            channel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
        }
    }



}
